//#include <glib.h>
//#include <glib/gprintf.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <fcntl.h>
#include "rpi_i2c.h"

rpi_i2c::rpi_i2c(const char *d,const char a,const char r) {
error_str =0;
buf =0;
device_loc=0;
fd =0;

/*bits = 8;
speed = 450000;
delay = 2;
*/

if (d) setDevice(d);
if (error_str) return;
if (a) setAddress(a);
if (error_str) return;
if (r) setRegister(r);
if (error_str) return;
//if (v) setValue(v);


}
rpi_i2c::~rpi_i2c() { 
    closei2c();
    if (device_loc) delete device_loc;
    device_loc =0;
    if (error_str) delete error_str;
    error_str =0;
    if (buf) delete buf;
    buf =0;
}
void rpi_i2c::setDevice(const char *d) {
    if (error_str) return;
    if (!d) { device_loc =0; return; }
    if (device_loc) delete device_loc;
    const int devlen = strlen(d);
    device_loc = new char[devlen];
    strcpy(device_loc,d);
}

void rpi_i2c::setError(const char *e) {
    if (!e) { e =0; return; }
    if (error_str) delete error_str;
    const int errlen = strlen(e);
    error_str = new char[errlen];
    strcpy(error_str,e);
    printf("%s\n");
    }


void rpi_i2c::closei2c() {
    if (fd) close(fd);
    fd =0;
}

void rpi_i2c::setAddress(const char a) {

    if (fd) closei2c();
    if ((fd = open(device_loc,O_RDWR)) < 0) {
        setError("Failed to open the bus.");
        /* ERROR HANDLING; you can check errno to see what went wrong */
        return;
    }
    addr_v =a;
    if (ioctl(fd,I2C_SLAVE,addr_v) < 0) {
        setError("Failed to acquire bus access and/or talk to slave.\n");
        /* ERROR HANDLING; you can check errno to see what went wrong */
        return;
    }
}
void rpi_i2c::setRegister(char r) { 
    if (error_str) return;
    
   /* char bufw [1];
    bufw[0] =r;
    //bufw[1] = w;
    
    if (write(fd,&w,1) != 2) {
        setError("Failed to write to the i2c bus.\n");
    }*/
    
    register_v = r; 
}

char* rpi_i2c::device() { return device_loc; }
char rpi_i2c::address() { return addr_v; }
char rpi_i2c::reg() { return register_v; }
char rpi_i2c::value() { return value_v; }

char* rpi_i2c::error() { return error_str; }

void rpi_i2c::write8bit(char w) {
    
    char bufw [2];
    bufw[0] =register_v;
    bufw[1] = w;
    
    if (write(fd,&bufw,2) != 2) {
        setError("write 8 bit Failed to write to the i2c bus.\n");
    }
}
void rpi_i2c::read8bit(char *r){
    char bufw [1];
    bufw[0] =register_v;
    
 if (write(fd,&register_v,1) != 1) {
        setError("read set reg Failed to write to the i2c bus.\n");
    }
    if (error_str) return;
    if (read(fd,r,1) != 1) {
    setError("Failed to read from the i2c bus.");    
    }
}


uint8_t rpi_i2c::read8bitreg(char r){
uint8_t ret =0;
 if (write(fd,&r,1) != 1) {
        setError("read set reg Failed to write to the i2c bus.\n");
    }
    if (error_str) return ret;
    if (read(fd,&ret,1) != 1) {
    setError("Failed to read from the i2c bus.");    
    }
    return ret;
}


uint16_t rpi_i2c::read16bitreg(char r) {
    uint16_t ret =0;
    uint8_t r8b[] ={0,0};
    
    
    //uint8_t ret =0;
    if (write(fd,&r,1) != 1) {
        setError("read set reg Failed to write to the i2c bus.\n");
    }
    if (error_str) return ret;
    if (read(fd,r8b,2) != 2) {
    setError("Failed to read from the i2c bus.");    
    }
    
    
    ret = (uint16_t(r8b[0]) << 8) | uint16_t(r8b[1]);
    return ret;
}

    